{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Debugging with [`pdb`](https://docs.python.org/3/library/pdb.html#module-pdb)\n",
    "Your program does not always behave how you would expect it to behave. If the origin of the mistake is unclear, debugging is usually the most effective to find the root cause of the unexpected behavior. The Python Standard Library has a built-in debugger which is a powerful tool for solving any issues related to your code."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `import pdb; pdb.set_trace()`\n",
    "The basic use case for debugging is that you want to stop the execution of your program at some certain point and monitor variable values or program execution in general from that specific point onward. You stop the execution at the point you want by setting a breakpoint into code by `import pdb; pdb.set_trace()` (note in Python versions >= 3.7, there's a shortcut: `breakpoint()`).\n",
    "\n",
    "When you execute your program, the execution will stop at this point and will enter to interactive debugger session. You can add as many breakpoints into your code as you want."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Useful commands\n",
    "See the full list [here](https://docs.python.org/3/library/pdb.html#debugger-commands).\n",
    "\n",
    "* `h` or `help`: Prints a list of available commands. If you give an argument, e.g. `help continue`, prints help of the `continue` command.\n",
    "* `l` or `list`: List a piece of code around the current position.\n",
    "* `n` or `next`: Execute next line.\n",
    "* `s` or `step`: Same as `next` but \"steps into\" the function called in the next line.\n",
    "* `c` or `continue`: Continue execution until next breakpoint.\n",
    "* `r` or `return`: Continue execution until the return of current function.\n",
    "* `q` or `quit`: Quit debugger and abort program execution.\n",
    "\n",
    "Note that you can see the value of any variable by typing the variable name during the debugging session. You can also execute arbitrary code during the debugging session."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Let's see how it works\n",
    "Uncomment the `import pdb; pdb.set_trace()` lines and execute the cell. Execute the program line by line by using the commands defined above. Try all the above mentioned commands at least once. Pay attention to the difference between `n` and `s`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class SuperGreeter:\n",
    "    def __init__(self, people_to_greet):\n",
    "        self.people = people_to_greet\n",
    "\n",
    "    def greet(self):\n",
    "        for person in self.people:\n",
    "            if person.islower():\n",
    "                self._greet_street_style(person)\n",
    "            elif len(person) > 7:\n",
    "                self._greet_hawaii(person)\n",
    "            else:\n",
    "                self._greet_polite(person)\n",
    "            \n",
    "    def _greet_polite(self, name):\n",
    "        greeting = \"G'day {}! How are you doing?\".format(name)\n",
    "        print(greeting)\n",
    "\n",
    "    def _greet_street_style(self, name):\n",
    "        # import pdb; pdb.set_trace()  # UNCOMMENT\n",
    "        name = name.upper()\n",
    "        print('WASSUP {}!?'.format(name))\n",
    "\n",
    "    def _greet_hawaii(self, name):\n",
    "        print('Aloha {}!'.format(name))\n",
    "\n",
    "\n",
    "def main():\n",
    "    people = ['John Doe', 'Donald', 'Lisa', 'alex']\n",
    "    # import pdb; pdb.set_trace()  # UNCOMMENT\n",
    "    greeter = SuperGreeter(people)\n",
    "    greeter.greet()\n",
    "\n",
    "\n",
    "main()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
